package com.qq.BFMRSE.Cache;

import java.util.HashMap;
import java.util.Iterator;

import org.apache.log4j.Logger;

import com.qq.BFMRSE.util.BFConstants;
import com.sun.tools.javac.resources.javac;

/**
 * 索引管理类，单例模式实现
 * @author yuanqiongqiong
 *
 */
public class indexCacheManager {
	private static indexCacheManager singleton=null;
	private static Logger log=Logger.getLogger(indexCacheManager.class);
	private HashMap<String, Object>cacheMap;
	private indexCacheManager(){
		super();
		cacheMap=new HashMap<String, Object>();
		clearThread thread=new clearThread();
		thread.start();
	}
	public static indexCacheManager getInstance(){
		if(singleton==null){
			synchronized (indexCacheManager.class) {
				if(singleton==null){
					singleton=new indexCacheManager();
				}
			}
		}
		return singleton;
	}
	public synchronized  void clearAll(){
		cacheMap.clear();
	}
	public synchronized  int getCacheSize(){
		return cacheMap.size();
	}
	/**
	 * 向缓存中添加新的cache
	 * @param key
	 * @param cache
	 */
	public synchronized  void addData2Cache(String key,Object data){
		if(Runtime.getRuntime().freeMemory()<=BFConstants.FREEMEMORY){
			log.warn("虚拟及内存不足，对缓存进行清理");
			clearAll();//清理缓存中所有数据
		}else {
			indexCache cache=new indexCache();
			cache.setValue(data);
			cache.setExpired(false);
			cache.setTimeout(System.currentTimeMillis()+BFConstants.CACHETIMEOUT);
			cache.setKey(key);
			cacheMap.put(key, cache);
		}
	}
	/**
	 * 获得缓存中数据
	 * @param key
	 * @return
	 */
	public synchronized  Object getCacheData(String key){
		indexCache ret=(indexCache)cacheMap.get(key);
		if(ret==null){
			return null;
		}
		//如果缓存数据已经标记过期或者判断过期
		if(cacheExpired(ret)){
			cacheMap.remove(key);
			log.info("缓存key="+key+"过期，进行清理");
			return null;
		}
		return ret.getValue();
	}
	/**
	 * 设置cache过期
	 * @param key
	 */
	public synchronized void setCacheExpired(String key){
		indexCache cache=(indexCache) cacheMap.get(key);
		cache.setExpired(true);
	}
	/**
	 * 判断cache是否过期
	 * @param cache
	 * @return
	 */
	public  boolean cacheExpired(indexCache cache){
		if(cache==null){
			return false;
		}
		long nowDt=System.currentTimeMillis();
		long cacheDt=cache.getTimeout();
		if(cache.isExpired()||cacheDt<=0||cacheDt>=nowDt){
			return false;
		}else{
			return true;
		}
	}
	/**
	 * 返回类型为type的key的个数
	 * @param type
	 * @return
	 */
	public int getTypeSize(String type){
		int k=0;
		String key="";
		Iterator iterator=cacheMap.entrySet().iterator();
		while(iterator.hasNext()){
			java.util.Map.Entry entry = (java.util.Map.Entry) iterator.next(); 
			key=(String)entry.getKey();
			if(key.indexOf(type)!=-1){
				k++;
			}
		}
		return k;
	}
	public boolean isContain(String key){
		return cacheMap.containsKey(key);
	}
	public String toString(){
		StringBuffer sb=new StringBuffer();
		sb.append("size="+cacheMap.size());
		sb.append(",key=");
		Object []keys=cacheMap.keySet().toArray();
		for(int i=0;i<keys.length;i++){
			sb.append((String)keys[i]+" ");
		}
		return sb.toString();
	}
	/**
	 * 缓存清理线程，定时对cacheMap进行清理
	 * @author yuanqiongqiong
	 *
	 */
	private class clearThread extends Thread{
		public clearThread() {
			// TODO Auto-generated constructor stub
			setName("clearCache");
		}
		public void run(){
			while(true){
				long now=System.currentTimeMillis();
				Object []keys=cacheMap.keySet().toArray();
				for(int i=0;i<keys.length;i++){
					indexCache cache=(indexCache)cacheMap.get(keys[i]);
					if(cacheExpired(cache)){
						synchronized (cacheMap) {
							String key=(String)keys[i];
							cacheMap.remove(key);
							log.info("定时清理线程，缓存key="+key+"过期，进行清理");
						}
					}
				}
				try {
					Thread.sleep(BFConstants.CACHETIMEOUT);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
